package com.amirarcane.lockscreen.andrognito.pinlockview;

import com.amirarcane.lockscreen.ResourceTable;
import com.amirarcane.lockscreen.util.ResUtil;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.*;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.transition.Transition;
import ohos.app.Context;
import ohos.global.resource.NotExistException;
import ohos.global.resource.ResourceManager;
import ohos.global.resource.WrongTypeException;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * It represents a set of indicator dots which when attached with  PinLockView
 * can be used to indicate the current length of the input
 */

public class IndicatorDots extends DirectionalLayout {

    @Retention(RetentionPolicy.SOURCE)
    public @interface IndicatorType {
        int FIXED = 0;
        int FILL = 1;
        int FILL_WITH_ANIMATION = 2;
    }

    private static final int DEFAULT_PIN_LENGTH = 4;
    private static final int DEFAULT_ANIMATION_DURATION = 200;

    private int mDotDiameter;
    private int mDotSpacing;
    private ShapeElement mFillDrawable;
    private ShapeElement mEmptyDrawable;
    private int mPinLength;
    private int mIndicatorType;

    private int mPreviousLength;

    public IndicatorDots(Context context) {
        this(context, null);
    }

    public IndicatorDots(Context context, AttrSet attrs) {
        this(context, attrs, 0);
    }

    public IndicatorDots(Context context, AttrSet attrs, int defStyleAttr) {
        super(context, attrs, String.valueOf(defStyleAttr));


        try {
            mDotDiameter =(int) ResUtil.getDimen(getContext(),ResourceTable.Float_dot_diameter);
            mDotSpacing = (int) ResUtil.getDimen(getContext(),ResourceTable.Float_dot_spacing);

            mFillDrawable = new ShapeElement();
            mFillDrawable.setShape(ShapeElement.OVAL);
            mFillDrawable.setRgbColor(RgbColor.fromArgbInt(getColor(getContext(),ResourceTable.Color_dot_filled)));

            mEmptyDrawable = new ShapeElement();
            mEmptyDrawable.setShape(ShapeElement.OVAL);
            mEmptyDrawable.setRgbColor(RgbColor.fromArgbInt(getColor(getContext(),ResourceTable.Color_dot_empty)));
            mEmptyDrawable.setStroke(1,RgbColor.fromArgbInt(getColor(getContext(),ResourceTable.Color_dot_border)));

            mPinLength = (int) ResourceUtils.getDimensionInPx(getContext(), DEFAULT_PIN_LENGTH);
            mIndicatorType = (int) ResourceUtils.getDimensionInPx(getContext(),
                    IndicatorType.FIXED);

        } finally {

        }
        initView(context);
    }

    public static int getColor(Context context, int id) {
        int result = 0;
        if (context == null) {
            return result;
        }
        ResourceManager manager = context.getResourceManager();
        if (manager == null) {
            return result;
        }
        try {
            result = manager.getElement(id).getColor();
        } catch (IOException e ) {;
        } catch (NotExistException e) {
        } catch (WrongTypeException e) {
        }
        ;
        return result;
    }
    private void initView(Context context) {
        setOrientation(Component.HORIZONTAL);
        if (mIndicatorType == 0) {
            for (int i = 0; i < mPinLength; i++) {
                Component dot = new Component(context);
                emptyDot(dot);

                DirectionalLayout.LayoutConfig params = new DirectionalLayout.LayoutConfig(mDotDiameter,
                        mDotDiameter);
                params.setMargins(mDotSpacing, 0, mDotSpacing, 0);
                dot.setLayoutConfig(params);

                addComponent(dot);
            }
        } else if (mIndicatorType == 2) {
            Transition layoutTransition = new Transition();
            layoutTransition.setDuration(DEFAULT_ANIMATION_DURATION);
        }
    }

    @Override
    public boolean isBoundToWindow() {
        super.isBoundToWindow();
        // If the indicator type is not fixed
        if (mIndicatorType != 0) {
            ComponentContainer.LayoutConfig params = this.getLayoutConfig();
            params.height = mDotDiameter;
            postLayout();
        }
        return false;
    }

    void updateDot(int length) {

        if (mIndicatorType == 0) {
            if (length > 0) {
                if (length > mPreviousLength) {

                 fillDot(getComponentAt(length - 1));
                } else {

                   emptyDot(getComponentAt(length));
                }
                mPreviousLength = length;
            } else {
                // When {@code mPinLength} is 0, we need to reset all the views back to empty

                for (int i = 0; i < getChildCount(); i++) {
                  Component v = getComponentAt(i);
                   emptyDot(v);
                }
                mPreviousLength = 0;
            }
        } else {
            if (length > 0) {
                if (length > mPreviousLength) {
                    Component dot = new Component(getContext());
                    fillDot(dot);

                    DirectionalLayout.LayoutConfig params = new DirectionalLayout.LayoutConfig(mDotDiameter,
                            mDotDiameter);
                    params.setMargins(mDotSpacing, 0, mDotSpacing, 0);
                    dot.setLayoutConfig(params);

                    addComponent(dot, length - 1);
                } else {
                    removeComponentAt(length);
                }
                mPreviousLength = length;
            } else {
                removeAllComponents();
                mPreviousLength = 0;
            }
        }
    }

    private void emptyDot(Component dot) {
        dot.setBackground(mEmptyDrawable);

    }

    private void fillDot(Component dot) {

        dot.setBackground(mFillDrawable);
  }


    public void setPinLength(int pinLength) {
        this.mPinLength = pinLength;
        removeAllComponents();
        initView(getContext());
    }


    public void setIndicatorType(int type) {
        this.mIndicatorType = type;
        removeAllComponents();
        initView(getContext());
    }
}